package com.xnyzc.lhy.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import com.xnyzc.lhy.common.constant.CommonConstant;
import com.xnyzc.lhy.common.entity.Qd;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.EMethod;
import org.springframework.util.MultiValueMap;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

/**
 * 转换工具类
 */
public class ConvertUtil {

    /**
     * 转换实体
     *
     * @param obj
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T changeObj(byte[] obj, Class<T> tClass) throws UnsupportedEncodingException {
        return JSON.parseObject(new String(obj, CommonConstant.UTF8), tClass);
    }

    /**
     * 转换实体
     *
     * @param obj
     * @param tClass
     * @param <T>
     * @return
     */
    public static <T> T changeObj(Object obj, Class<T> tClass) {
        if (obj instanceof Serializable) {
            return JSON.parseObject(JSON.toJSONString(obj), tClass);
        }
        else {
            return JSON.parseObject(obj.toString(), tClass);
        }

    }

    public static <T> T changeObj(Object obj, TypeReference<T> tClass) {
        if (obj instanceof Serializable) {
            return JSON.parseObject(JSON.toJSONString(obj), tClass);
        }
        else {
            return JSON.parseObject(obj.toString(), tClass);
        }
    }

    /**
     * 转换MulitMap
     *
     * @param map
     * @param <T>
     * @param <V>
     * @return
     */
    public static <T, V> List<Qd> convertMulitMap(MultiValueMap<T, V> map) {
        if (CheckUtil.objIsEmpty(map)) {
            return null;
        }

        List<Qd> rtnList = Lists.newLinkedList();

        for (T key : map.keySet()) {
            rtnList.add(Qd.create().add("key", key).add("value", map.get(key)));
        }

        return rtnList;
    }

    /**
     * 转换int，无法转换返回null
     *
     * @param o
     * @return
     */
    public static Integer toIntNonException(Object o) {
        if (o == null) {
            return null;
        }

        try {
            return Integer.parseInt(o.toString());
        }
        catch (Exception e) {
            return null;
        }
    }

    /**
     * 转换为int
     *
     * @param o
     * @return
     */
    public static int toInt(Object o) {
        if (o == null) {
            return 0;
        }

        String str = o.toString();
        //转换为空
        if (CheckUtil.strIsEmpty(str)) {
            return 0;
        }

        try {
            return Integer.parseInt(str);
        }
        catch (Exception e) {
            throw new PangException(EErrorCode.unkown, "err to parse:" + str);
        }
    }

    /**
     * 转换为long
     *
     * @param o
     * @return
     */
    public static long toLong(Object o) {
        if (o == null) {
            return 0L;
        }

        String str = o.toString();
        //转换为空
        if (CheckUtil.strIsEmpty(str)) {
            return 0L;
        }

        try {
            return Long.parseLong(str);
        }
        catch (Exception e) {
            throw new PangException(EErrorCode.unkown, "err to parse:" + str);
        }
    }

    /**
     * 转换为double
     *
     * @param o
     * @return
     */
    public static double toDouble(Object o) {
        if (o == null) {
            return 0d;
        }

        String str = o.toString();
        //转换为空
        if (CheckUtil.strIsEmpty(str)) {
            return 0d;
        }

        try {
            return Double.parseDouble(str);
        }
        catch (Exception e) {
            throw new PangException(EErrorCode.unkown, "err to parse:" + str);
        }
    }

    /**
     * 转换为boolean
     *
     * @param o
     * @return
     */
    public static boolean toBoolean(Object o) {
        if (o == null) {
            return false;
        }

        String str = o.toString();
        //转换为空
        if (CheckUtil.strIsEmpty(str)) {
            return false;
        }

        try {
            return Boolean.parseBoolean(str);
        }
        catch (Exception e) {
            throw new PangException(EErrorCode.unkown, "err to parse:" + str);
        }
    }


    /**
     * 转换为string
     *
     * @param o
     * @return
     */
    public static String toString(Object o) {
        if (o == null) {
            return null;
        }

        String str = o.toString();
        //转换为空
        if (CheckUtil.strIsEmpty(str)) {
            return "";
        }

        try {
            return str;
        }
        catch (Exception e) {
            throw new PangException(EErrorCode.unkown, "err to parse:" + str);
        }
    }

    /**
     * 下划线转驼峰
     *
     * @return
     */
    public static String toCamel(String source) {
        if (CheckUtil.strIsEmpty(source)) {
            return source;
        }

        if (source.indexOf('_') > 0) {
            return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, source);
        }

        return source;
    }

    /**
     * 获取输入值的get方法
     *
     * @param resource
     * @return
     */
    public static String makeMethodName(String resource, EMethod method) {
        if (CheckUtil.objIsEmpty(resource)) {
            return resource;
        }

        //需要进行下划线转驼峰
        StringBuilder sb = new StringBuilder(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, resource));
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        sb.insert(0, method.name());

        return sb.toString();
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @return
     */
    public static int getSecondTimestamp() {
        return getSecondTimestamp(new Date());
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @return
     */
    public static int getSecondTimestamp(Date date) {
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        }
        else {
            return 0;
        }
    }


    /**
     * 去除字符串中的\r\n\t
     *
     * @return
     */
    public static String replaceRnt(String input) {
        if (CheckUtil.objIsEmpty(input)) {
            return input;
        }

        return input.replaceAll("\r|\n", "").replaceAll("\t", "");
    }

    /**
     * * 检测是否有emoji字符
     * * @param source 需要判断的字符串
     * * @return 一旦含有就抛出
     */
    public static boolean containsEmoji(String source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (!notisEmojiCharacter(codePoint)) {
                //判断确认有表情字符
                return true;
            }
        }
        return false;
    }

    /**
     * * 非emoji表情字符判断
     * * @param codePoint
     * * @return
     */
    private static boolean notisEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <=
                0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    public static String filterEmoji(String source) {

        if (CheckUtil.strIsEmpty(source)) {
            return source;
        }

        source = source.replaceAll("[^\\u0000-\\uFFFF]", "");

        if (!containsEmoji(source)) {
            // 如果不包含，直接返回
            return source;
        }
        // 该buf保存非emoji的字符
        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (notisEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }

        if (buf == null) {
            // 如果没有找到非emoji的字符，则返回无内容的字符串
            return "";
        }
        else {
            if (buf.length() == len) {
                buf = null;
                return source;
            }
            else {
                return buf.toString();
            }
        }
    }

}
